//package com.stanwind.netty.core.subscribe;
//
//import org.apache.ibatis.session.SqlSession;
//import org.jboss.netty.channel.Channel;
//import pw.goyd.db.RedisUtil;
//import pw.goyd.db.mapping.PlayerMapper;
//import pw.goyd.game.api.CalcCards;
//import pw.goyd.game.api.DBDone;
//import pw.goyd.game.constant.enumcard.HandCardsWeight;
//import pw.goyd.game.constant.setting.Command;
//import pw.goyd.game.constant.setting.LuckyPool;
//import pw.goyd.game.logic.*;
//import pw.goyd.game.model.Card;
//import pw.goyd.game.model.LuckyAward;
//import pw.goyd.game.model.Player;
//import pw.goyd.game.server.Log;
//import pw.goyd.game.server.LoginList;
//import pw.goyd.game.server.BootstrapServer;
//import pw.goyd.protocol.model.Response;
//import redis.clients.jedis.Jedis;
//import redis.clients.jedis.exceptions.JedisException;
//
//import java.util.ArrayList;
//import java.util.List;
//
///**
// * 玩家扩展类
// *
// * @author StanWind
// */
//public class PlayerCustomer extends Player implements
//        Comparable<PlayerCustomer> {
//
//    private BinaryRedisPubSubListener binaryRedisPubSubListener;
//    // session channel
//    private Channel channel;
//    private long channelID;
//    private Jedis jedis;
//    // 游戏类
//    private int roomID = -1;
//    private boolean isReady = false;
//    private List<Card> cards;
//    private int declarer = 1;       // 抢庄倍数
//    private int bet = -1;           // 玩家倍数
//    // 牌型信息
//    private Card resCard;           // 最大的牌
//    private HandCardsWeight resType;// 点数
//    private int changingGolds;      // 这把变化的coin
//
//    //~~~~~~~~~~~~~~~订阅部分
//    private Thread boardcastT;
//    private Thread roomT;
//
//    public PlayerCustomer() {
//        cards = new ArrayList<>();
//    }
//
//    public long getChannelID() {
//        return channelID;
//    }
//
//    public void setChannelID(long channelID) {
//        this.channelID = channelID;
//    }
//
//    public int getChangingGolds() {
//        return changingGolds;
//    }
//
//    public void setChangingGolds(int changingGolds) {
//        this.changingGolds = changingGolds;
//    }
//
//    /**
//     * 每局游戏结束
//     */
//    public void gameFinish() {
//        setAll_times(getAll_times() + 1);   // 增加场次
//        if (getChangingGolds() > 0)
//            setWin_times(getWin_times() + 1);
//        if (getGold() < 0)
//            setGold(0);
//
//        savePlayer();
//        setChangingGolds(0);
//    }
//
//    public Card getResCard() {
//        return resCard;
//    }
//
//    public void setResCard(Card resCard) {
//        this.resCard = resCard;
//    }
//
//    public HandCardsWeight getResType() {
//        return resType;
//    }
//
//    public void setResType(HandCardsWeight resType) {
//        this.resType = resType;
//    }
//
//    public List<Card> getCards() {
//        return cards;
//    }
//
//    public void setCards(List<Card> cards) {
//        this.cards = cards;
//    }
//
//    public int getDeclarer() {
//        return declarer;
//    }
//
//    public void setDeclarer(int declarer) {
//        this.declarer = declarer;
//    }
//
//    public int getBet() {
//        return bet;
//    }
//
//    public void setBet(int bet) {
//        this.bet = bet;
//    }
//
//    public boolean isReady() {
//        return isReady;
//    }
//
//    public void setReady(boolean isReady) {
//        this.isReady = isReady;
//    }
//
//    public Channel getChannel() {
//        return channel;
//    }
//
//    public void setChannel(Channel channel) {
//        this.channel = channel;
//        setChannelID(channel.getId());
//    }
//
//    public int getRoomID() {
//        return roomID;
//    }
//
//    public void setRoomID(int roomID) {
//        this.roomID = roomID;
//    }
//
//    public Jedis getJedis() {
//        return jedis;
//    }
//
//    public void setJedis(Jedis jedis) {
//        this.jedis = jedis;
//    }
//
//    public BinaryRedisPubSubListener getBinaryRedisPubSubListener() {
//        return binaryRedisPubSubListener;
//    }
//
//    public void setBinaryRedisPubSubListener(
//            BinaryRedisPubSubListener binaryRedisPubSubListener) {
//        this.binaryRedisPubSubListener = binaryRedisPubSubListener;
//    }
//
//    /**
//     * 信息写入数据库
//     */
//    public void savePlayer() {
//        DBDone.updatePlayer(this);
//    }
//
//    /**
//     * 保存钻石
//     */
//    public void saveDiamond() {
//        SqlSession session = BootstrapServer.sessionFactory.openSession();
//        PlayerMapper playerMapper = session.getMapper(PlayerMapper.class);
//        playerMapper.updateDiamond(this);
//        session.commit();
//        session.close();
//    }
//
//    /**
//     * 监听大厅
//     */
//    public void psub() {
//        //TODO 长时间处于idel 可能Jedis Exception
//        //阻塞监听线程
//        boardcastT = new Thread(() -> {
//            Log.getLogger().info(
//                    "订阅---->" + "玩家[" + getNickname() + "] 订阅全局");
//            try {
//                byte[] b = "broadcast.*".getBytes();
//                jedis.psubscribe(binaryRedisPubSubListener,
//                        b);
//            } catch (JedisException e) {
//                Log.getLogger().error("idle long 未登陆？？psub", e);
//                unsub();
//                //boardcastT.start();
//            } catch (ClassCastException e) {
//                Log.getLogger().error("ClassCast", e);
//                unsub();//全部取消订阅
//            }
//
//        });
//
//        boardcastT.start();
//    }
//
//    /**
//     * 监听房间
//     */
//    public void psubRoom() {
//        // 阻塞监听线程
//        roomT = new Thread(() -> {
//            Log.getLogger().info(
//                    "订阅---->" + "玩家[" + getNickname() + "] 进入房间[" + roomID
//                            + "]");
//            try {
//                jedis.psubscribe(binaryRedisPubSubListener,
//                        ("room." + roomID).getBytes());
//            } catch (JedisException e) {
//                Log.getLogger().error("idle long 未登陆－－psubroom", e);
//                LoginList.removePlayer(this);
//            } catch (ClassCastException e) {
//                Log.getLogger().error("ClassCast", e);
//                setRoomID(-1);
//                unsubRoom();
//            }
//        });
//        roomT.start();
//    }
//
//
//    /**
//     * 取消订阅房间
//     */
//    public void unsubRoom() {
//        Log.getLogger().info(
//                "订阅---->" + "玩家[" + getNickname() + "] 退出房间[" + roomID + "]");
//        unsub(("room." + roomID).getBytes());
//        if (roomT != null) {
//            roomT.stop();
//            roomT = null;
//        }
//
//
////        // TODO: 16/11/11 解决了由于取消订阅再次订阅导致的消息延迟到达 造成的客户端数据混乱 因此给客户端重新分配订阅客户端 但是资源消耗增加
////        Jedis temp = getJedis();
////        setJedis(RedisUtil.getJedis());
////        setBinaryRedisPubSubListener(new BinaryRedisPubSubListener());
////        Log.getLogger().info("Instance Finish");
////        RedisUtil.returnResource(temp);
//    }
//
//    /**
//     * 取消所有订阅
//     */
//    public void unsub() {
//        Log.getLogger().debug(
//                "订阅---->玩家[" + getNickname() + "]取消所有订阅");
//        if (binaryRedisPubSubListener != null)
//            binaryRedisPubSubListener.unsubscribe();
//
//        unsubRoom();
//        if (boardcastT != null) {
//            boardcastT.stop();
//            boardcastT = null;
//        }
//
//        this.setBinaryRedisPubSubListener(null);
//    }
//
//    /**
//     * 取消订阅频道 自己结束线程
//     *
//     * @param channel 频道名
//     */
//    protected void unsub(final byte[] channel) {
//        if (binaryRedisPubSubListener != null)
//            binaryRedisPubSubListener.unsubscribe(channel);
//    }
//
//    //~~~~~~~~~~~~~~~~~~~~游戏包部分
//
//    /**
//     * 不能进入房间
//     */
//    public void sendKickOutRoom() {
//        Response response = new Response();
//        KickOutRoomResponse kickOutRoomResponse = new KickOutRoomResponse();
//        response.setData(kickOutRoomResponse.getBytes());
//        response.setTime(0);
//        response.setCmd(Command.CMD_KICKOUTROOM);
//
//        //Log.getLogger().debug("Kick--->"+response.getAllBytes());
//        this.getChannel().write(response);
//    }
//
//    /**
//     * 发牌
//     */
//    public void sendCards() {
//        DispatchResponse dispatchResponse = new DispatchResponse();
//        dispatchResponse.setCards(this.cards);
//        Response response = new Response();
//        response.setCmd(Command.CMD_DISPATCH);
//        response.setData(dispatchResponse.getBytes());
//        response.setTime(0);
//        this.channel.write(response);
//    }
//
//    /**
//     * 发送最后一张牌
//     */
//    public void sendLastCard() {
//        List<Card> lastCard = new ArrayList<>();
//        lastCard.add(cards.get(cards.size() - 1));
//
//        DispatchResponse dispatchResponse = new DispatchResponse();
//        dispatchResponse.setCards(lastCard);
//        Response response = new Response();
//        response.setCmd(Command.CMD_DISPATCH);
//        response.setData(dispatchResponse.getBytes());
//        response.setTime(0);
//        this.channel.write(response);
//    }
//
//    public void sendPlayerInfo() {
//        PlayerInfoResponse playerInfoResponse = new PlayerInfoResponse();
//        playerInfoResponse.setPlayer(this);
//        Response response = new Response();
//        response.setData(playerInfoResponse.getBytes());
//        response.setTime(0);
//        response.setCmd(Command.CMD_PLAYERINFO);
//        this.getChannel().write(response);
//    }
//
//    /**
//     * 推送分数
//     */
//    public void sendDeclarer() {
//        Response response = new Response();
//        DeclarerResponse declarerResponse = new DeclarerResponse();
//        declarerResponse.setPlayerCustomer(this);
//        response.setCmd(Command.CMD_DECLARER);
//        response.setData(declarerResponse.getBytes());
//        response.setTime(0);
//        RedisUtil.pubRoom(this.getRoomID(), response.getAllBytes());
//    }
//
//    /**
//     * 推送倍数
//     */
//    public void sendBet() {
//        Response response = new Response();
//        BetResponse betResponse = new BetResponse();
//        betResponse.setPlayer(this);
//        response.setCmd(Command.CMD_BET);
//        response.setData(betResponse.getBytes());
//        response.setTime(0);
//        RedisUtil.pubRoom(this.getRoomID(), response.getAllBytes());
//    }
//
//    /**
//     * 计算牌型
//     */
//    public void calcCards() {
//        this.setResCard(CalcCards.calcMaxCard(this.getCards()));
//        this.setResType(CalcCards.calcType(this.getCards()));
//        Log.getLogger().info(
//                getResType().name() + "----" + getResCard().weight);
//    }
//
//    /**
//     * push to room broadcast and judge the room state
//     */
//    public void sendLeaveRoom() {
//        Response response = new Response();
//        ExitRoomResponse exitRoomResponse = new ExitRoomResponse();
//        exitRoomResponse.setAccount_id(getAccount_id());
//        response.setCmd(Command.CMD_EXITROOM);
//        response.setData(exitRoomResponse.getBytes());
//        response.setTime(0);
//
//        if (roomID != -1) {
//            RedisUtil.pubRoom(roomID, response.getAllBytes());
//        }
//    }
//
//    @Override
//    public String toString() {
//
//        return "Jedis State:" + jedis.isConnected() + " NickName:"
//                + getNickname() + " AccountID:" + getAccount_id() + " ChannelID:" + getChannelID()
//                + " Channel State: open." + channel.isOpen() + " connected."
//                + channel.isConnected() + " writable." + channel.isWritable()
//                + " readable." + channel.isReadable();
//
//    }
//
//    @Override
//    public int compareTo(PlayerCustomer o) {
//        int compare = 0;
//        // 比较牌型
//        int result = this.getResType().ordinal() - o.getResType().ordinal();
//        if (result > 0) {
//            compare = 1;
//        } else if (result < 0) {
//            compare = -1;
//        } else if (result == 0) {
//            // 比较最大牌
//            result = this.getResCard().compareTo(o.getResCard());
//            if (result > 0) {
//                compare = 1;
//            } else if (result < 0) {
//                compare = -1;
//            }
//        }
//
//        return compare;
//    }
//
//    public void saveLuckyAward(LuckyAward luckyAward) {
//        if (luckyAward.getLuckyType() == LuckyPool.LuckyType.Gold) {
//            setGold(getGold() + luckyAward.getValue());
//            savePlayer();
//        } else if (luckyAward.getLuckyType() == LuckyPool.LuckyType.Diamond) {
//            setDiamond(getDiamond() + luckyAward.getValue());
//            savePlayer();
//        }
//    }
//
//
//}